package com.nuoniu.sibanyun.service.production.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.lang.StringUtils;
import com.nuoniu.sibanyun.entity.bo.*;
import com.nuoniu.sibanyun.entity.dto.ProductionWorkSearchDto;
import com.nuoniu.sibanyun.entity.dto.VProductionWorkDetailSplitDto;
import com.nuoniu.sibanyun.entity.dto.VProductionWorkMainSearchDto;
import com.nuoniu.sibanyun.entity.dto.VProductionWorkMainSplitDto;
import com.nuoniu.sibanyun.entity.dto.statistics.ProductionWorkCumSummaryDto;
import com.nuoniu.sibanyun.entity.dto.statistics.ProductionWorkInAndPickDto;
import com.nuoniu.sibanyun.entity.dto.statistics.ProductionWorkMonthSummaryDto;
import com.nuoniu.sibanyun.entity.erp.ErpNumberSet;
import com.nuoniu.sibanyun.entity.production.*;
import com.nuoniu.sibanyun.entity.so.VSaleDeliveryMain;
import com.nuoniu.sibanyun.entity.vo.*;
import com.nuoniu.sibanyun.entity.vo.reportVo.*;
import com.nuoniu.sibanyun.mapper.erp.ErpNumberSetMapper;
import com.nuoniu.sibanyun.mapper.production.VProductionWorkMainMapper;
import com.nuoniu.sibanyun.service.crm.ICrmGoodsService;
import com.nuoniu.sibanyun.service.erp.IErpAccountService;
import com.nuoniu.sibanyun.service.erp.IErpNumberSetService;
import com.nuoniu.sibanyun.service.erp.IErpVoucherDesignService;
import com.nuoniu.sibanyun.service.production.IVProductionPickReturnMainService;
import com.nuoniu.sibanyun.service.production.IVProductionWorkDetailService;
import com.nuoniu.sibanyun.service.production.IVProductionWorkInventoryDetailService;
import com.nuoniu.sibanyun.service.production.IVProductionWorkMainService;
import com.nuoniu.sibanyun.service.utils.ErpUtils;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 生产加工单 服务实现类
 * </p>
 *
 * @author 小啊刚
 * @since 2021-03-13
 */
@Service
public class VProductionWorkMainServiceImpl extends ServiceImpl<VProductionWorkMainMapper, VProductionWorkMain> implements IVProductionWorkMainService {

    @Autowired
    private ErpNumberSetMapper numberSetMapper;
    @Autowired
    private IErpNumberSetService numberSetService;
    @Autowired
    private IErpAccountService accountService;
    @Autowired
    private IVProductionWorkDetailService productionWorkDetailService;
    @Autowired
    private IErpVoucherDesignService erpVoucherDesignService;
    @Autowired
    private IVProductionWorkInventoryDetailService productionWorkInventoryDetailService;
    @Autowired
    private IVProductionPickReturnMainService productionPickReturnMainService;
    @Autowired
    private ICrmGoodsService crmGoodsService;


    @Override
    public String getCode() {
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = accountService.getCurrentAccountId();
        ErpNumberSet numberSet = numberSetMapper.getByCode("ProductionWork", userInfo.getCompanyId(), currentAccountId);
        String dateStr = numberSet.getMedian() == 1 ? "%Y-%m-%d" : "%Y-%m";
        String code = baseMapper.getNewestCode(userInfo.getCompanyId(), dateStr,"ProductionWork");
        return numberSetService.getCode(numberSet, code);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveProductionWorkMain(VProductionWorkMain productionWorkMain) {
        Boolean isNewMain = false;
        Integer currentAccountId = accountService.getCurrentAccountId();
        UserInfo userInfo = UserThreadLocal.get();
        Long mainId = productionWorkMain.getId();
        String dataSource = productionWorkMain.getDataSource();
        if (StringUtils.isBlank(dataSource)) {
            throw new NuoNiuException("参数错误");
        }
        if (null == mainId ) {
            isNewMain = true;
            if ("ProductionWork".equals(dataSource)){
                productionWorkMain.setVoucherCode(getCode());
            }else if( "DelegateProductionWork".equals(dataSource)){
                productionWorkMain.setVoucherCode(getDelegateCode());
            }
            productionWorkMain.setVoucherState(-1);
            productionWorkMain.setCompanyId(userInfo.getCompanyId());
            productionWorkMain.setAccountId(currentAccountId);
            productionWorkMain.setCreateUserId(userInfo.getUserId());
            productionWorkMain.setCreateUserName(userInfo.getRealName());
        }else{
            VProductionWorkMain oldProductionWorkMain = getById(mainId);
            if(oldProductionWorkMain.getVoucherState() > 0) {
                throw new NuoNiuException("该单据已审核，不能修改");
            }
            if(!oldProductionWorkMain.getCreateUserId().equals(UserThreadLocal.get().getUserId())) {
                throw new NuoNiuException("只能修改自已数据");
            }
            //不可更新字段
            productionWorkMain.setVoucherCode(null);
        }
        List<VProductionWorkDetail> orderDetailList = productionWorkMain.getOrderDetailList();
        if (null == orderDetailList) {
            throw new NuoNiuException("请选择产品明细");
        }
        //计算 明细物料 总数
        BigDecimal totalQuantity =  productionWorkMain.getOrderDetailList().stream().map(VProductionWorkDetail::getBaseQuantity).reduce(BigDecimal.ZERO,BigDecimal::add);
        productionWorkMain.setTotalQuantity(totalQuantity.abs());
        /** 1.保存主表 */
        Boolean isMainOk = this.saveOrUpdate(productionWorkMain);
        /** 2.保存明细表 */
        if (isMainOk) {
            productionWorkDetailService.batchSave(productionWorkMain);

            if(null != productionWorkMain.getSourceVoucherId()){
                if(!"ProductionOrder".equals(productionWorkMain.getSourceVoucherType())) {
                    throw new NuoNiuException("加工单的来源单，只能是生产订单");
                }
                VoucherMainBo voucherMainBo = new VoucherMainBo();
                BeanUtils.copyProperties(productionWorkMain,voucherMainBo);
                voucherMainBo.setIsNewMain(isNewMain);
                List<VoucherDetailBo> voucherDetailBos = new ArrayList<>();
                orderDetailList.forEach(detail->{
                    VoucherDetailBo voucherDetailBo = new VoucherDetailBo();
                    voucherDetailBos.add(voucherDetailBo);
                    BeanUtils.copyProperties(detail,voucherDetailBo);
                });
                VoucherSearchBo voucherSearchBo = new VoucherSearchBo();
                voucherSearchBo.setSourceVoucherId(productionWorkMain.getSourceVoucherId());
                voucherSearchBo.setSourceVoucherType(productionWorkMain.getSourceVoucherType());
                voucherSearchBo.setVoucherId(productionWorkMain.getId().intValue());
                voucherSearchBo.setVoucherType(dataSource);
                erpVoucherDesignService.calculateSourceVoucher(voucherMainBo,voucherDetailBos,voucherSearchBo);
            }
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveOrderForInventory(VProductionWorkMainSplitDto productionWorkMainSplitDto) {
        List<VProductionWorkDetailSplitDto> orderDetailList = productionWorkMainSplitDto.getOrderDetailList();

        orderDetailList.forEach(detail->{
            VProductionWorkMain vProductionWorkMain = new VProductionWorkMain();
            BeanUtils.copyProperties(productionWorkMainSplitDto,vProductionWorkMain);
            if (null == detail.getOfficeId()) {
                throw new NuoNiuException("待分单明细没有选择车间");
            }
            vProductionWorkMain.setOfficeId(detail.getOfficeId());
            vProductionWorkMain.setOfficeName(detail.getOfficeName());
            VProductionWorkDetail productionWorkDetail = new VProductionWorkDetail();
            BeanUtils.copyProperties(detail,productionWorkDetail);
            List<VProductionWorkDetail> detailList = new ArrayList<>();
            detailList.add(productionWorkDetail);
            vProductionWorkMain.setOrderDetailList(detailList);
            saveProductionWorkMain(vProductionWorkMain);
        });
    }
    @Override
    public void submit(Long id, Integer status) {
        if(null == id || null == status || (null != status && (status > 0 || status < -1 ))) {
            throw new NuoNiuException("参数错误");
        }
        UserInfo userInfo = UserThreadLocal.get();
        VProductionWorkMain productionWorkMain = this.getById(id);
        if( null == productionWorkMain) {
            throw new NuoNiuException("记录不存在");
        }
        //校验状态
        Integer voucherState = productionWorkMain.getVoucherState();
        /**  统一校验 提交状态 */
        ErpUtils.checkSubmitStatus(voucherState,status);
        //提交
        productionWorkMain.setVoucherState(status);
        productionWorkMain.setSubmitDate(LocalDateTime.now());
        productionWorkMain.setSubmitUserId(userInfo.getUserId());
        productionWorkMain.setSubmitUserName(userInfo.getRealName());
        this.updateById(productionWorkMain);
    }

    @Override
    public void examine(Long id, Integer status) {
        UserInfo userInfo = UserThreadLocal.get();
        BigDecimal cumExecuteQuantity = getCumExecuteQuantity(id);
        if (status == 0 ){
            if ( null != cumExecuteQuantity && cumExecuteQuantity.compareTo(BigDecimal.ZERO) > 0) {
                throw new NuoNiuException("已经生单，不能弃审");
            }
            BigDecimal allDetailCumDispatchQuantity = getAllDetailCumDispatchQuantity(id);
            if(null != allDetailCumDispatchQuantity && allDetailCumDispatchQuantity.compareTo(BigDecimal.ZERO) > 0 ) {
                throw new NuoNiuException("已经生产派工单，不能弃审");
            }
            boolean haveFromWorkMainId = productionPickReturnMainService.isHaveFromWorkMainId(id);
            if (haveFromWorkMainId) {
                throw new NuoNiuException("已经开始领料，不能弃审");
            }
        }

        VProductionWorkMain productionWorkMain = new VProductionWorkMain();
        productionWorkMain.setVoucherState(status);
        productionWorkMain.setId(id);
        productionWorkMain.setReviewerDate(LocalDateTime.now());
        productionWorkMain.setReviewerUserId(userInfo.getUserId());
        productionWorkMain.setReviewerUserName(userInfo.getRealName());
        updateById(productionWorkMain);
    }

    @Override
    public BigDecimal getCumExecuteQuantity(Long id) {
        QueryWrapper<VProductionWorkMain> wrapper = new QueryWrapper();
        wrapper.select("cum_execute_quantity");
        wrapper.eq("id",id);
        VProductionWorkMain productionWorkMain = getOne(wrapper);
        return productionWorkMain.getCumExecuteQuantity();
    }

    @Override
    public BigDecimal getAllDetailCumDispatchQuantity(Long id) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = accountService.getCurrentAccountId();
        BigDecimal allDetailCumDispatchQuantity = baseMapper.getAllDetailCumDispatchQuantity(userInfo.getCompanyId(), currentAccountId, id);
        return allDetailCumDispatchQuantity;
    }


    @Override
    public List<VProductionWorkMain> listNotFinishMain(VProductionWorkMainSearchDto productionWorkMainSearchDto) {
//        Integer officeId = productionWorkMainSearchDto.getOfficeId();
//        if (null == officeId)throw new NuoNiuException("请选择车间");
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = accountService.getCurrentAccountId();
        List<VProductionWorkMain> vProductionWorkMains = baseMapper.listNotFinishMain(userInfo.getCompanyId(), currentAccountId, productionWorkMainSearchDto);
        return vProductionWorkMains;
    }

    @Override
    public List<VProductionWorkMain> listNotFinishMain2(VProductionWorkMainSearchDto productionWorkMainSearchDto) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = accountService.getCurrentAccountId();
        List<VProductionWorkMain> vProductionWorkMains = baseMapper.listNotFinishMain2(userInfo.getCompanyId(), currentAccountId, productionWorkMainSearchDto);
        return vProductionWorkMains;
    }


    @Override
    public void updateVoucherState(Long id, Integer voucherState) {
        UpdateWrapper<VProductionWorkMain> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",id);
        updateWrapper.set("voucher_state",voucherState);
        update(updateWrapper);
    }

    @Override
    public String getDelegateCode() {
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = accountService.getCurrentAccountId();
        ErpNumberSet numberSet = numberSetMapper.getByCode("DelegateProductionWork", userInfo.getCompanyId(), currentAccountId);
        String dateStr = numberSet.getMedian() == 1 ? "%Y-%m-%d" : "%Y-%m";
        String code = baseMapper.getNewestCode(userInfo.getCompanyId(), dateStr,"DelegateProductionWork");
        return numberSetService.getCode(numberSet, code);
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteDelegateById(Long id) {
        UserInfo userInfo = UserThreadLocal.get();
        VProductionWorkMain productionWorkMain = getById(id);
        if(productionWorkMain == null) {
            throw new NuoNiuException("单据已删除");
        }
        String dataSource = productionWorkMain.getDataSource();
        /**************  修改权限 *******************/
        if(!crmGoodsService.isHaveOperationRight(productionWorkMain.getCreateUserId().longValue())){
            throw new NuoNiuException("你没有权限操作该记录");
        }
        BigDecimal cumExecuteQuantity = productionWorkMain.getCumExecuteQuantity();
        if(null != cumExecuteQuantity && cumExecuteQuantity.compareTo(BigDecimal.ZERO) > 0){
            throw new NuoNiuException("单据已生成下一步单据，不能删除");
        }
        List<VProductionWorkDetail> orderDetails   = productionWorkDetailService.getDetailsByOrderId(id);
        //*** 如果 来源订单不为空,校验
        if(null != productionWorkMain.getSourceVoucherId()){
            VoucherMainBo voucherMainBo = new VoucherMainBo();
            BeanUtils.copyProperties(productionWorkMain,voucherMainBo);
            List<VoucherDetailBo> voucherDetailBos = new ArrayList<>();
            orderDetails.forEach(detail->{
                VoucherDetailBo voucherDetailBo = new VoucherDetailBo();
                voucherDetailBos.add(voucherDetailBo);
                BeanUtils.copyProperties(detail,voucherDetailBo);
            });
            VoucherSearchBo voucherSearchBo = new VoucherSearchBo();
            voucherSearchBo.setCalculateType(2);
            voucherSearchBo.setSourceVoucherId(productionWorkMain.getSourceVoucherId());
            voucherSearchBo.setSourceVoucherType(productionWorkMain.getSourceVoucherType());
            voucherSearchBo.setVoucherId(productionWorkMain.getId().intValue());
            voucherSearchBo.setVoucherType(dataSource);
            erpVoucherDesignService.calculateSourceVoucher(voucherMainBo,voucherDetailBos,voucherSearchBo);
        }
        removeById(id);
        productionWorkDetailService.removeByOrderId(id);
    }

    @Override
    public void examineDelegate(Long id, Integer status) {
        UserInfo userInfo = UserThreadLocal.get();
        BigDecimal cumExecuteQuantity = getCumExecuteQuantity(id);
        if (status == 0 ){
            if ( null != cumExecuteQuantity && cumExecuteQuantity.compareTo(BigDecimal.ZERO) > 0) {
                throw new NuoNiuException("已经生单，不能弃审");
            }
            boolean haveFromWorkMainId = productionPickReturnMainService.isHaveFromWorkMainId(id);
            if (haveFromWorkMainId) {
                throw new NuoNiuException("已经开始领料，不能弃审");
            }
        }
        VProductionWorkMain productionWorkMain = new VProductionWorkMain();
        productionWorkMain.setVoucherState(status);
        productionWorkMain.setId(id);
        productionWorkMain.setReviewerDate(LocalDateTime.now());
        productionWorkMain.setReviewerUserId(userInfo.getUserId());
        productionWorkMain.setReviewerUserName(userInfo.getRealName());
        updateById(productionWorkMain);
    }

    @Override
    public UnFinishProductionShowVo listUnFinishProductionShowVo(ProductionWorkSearchDto delegateProductionWorkSearchDto) {
        UnFinishProductionShowVo unFinishDelegateProductionShowVo = new UnFinishProductionShowVo();
        UserInfo userInfo = UserThreadLocal.get();
        Integer currentAccountId = accountService.getCurrentAccountId();
        List<UnFinishProductionWorkVo> unFinishDelegateProductionWorkVos = baseMapper.listUnFinishProductionWorkVo(userInfo.getCompanyId(), currentAccountId, delegateProductionWorkSearchDto);
        List<UnFinishInventoryDetailVo> unFinishDelegateInventoryDetailVos = baseMapper.listUnFinishInventoryDetailVo(userInfo.getCompanyId(), currentAccountId, delegateProductionWorkSearchDto);
        unFinishDelegateProductionShowVo.setUnFinishDelegateProductionWorkVoList(unFinishDelegateProductionWorkVos);
        unFinishDelegateProductionShowVo.setUnFinishDelegateInventoryDetailVoList(unFinishDelegateInventoryDetailVos);
        return unFinishDelegateProductionShowVo;
    }

    /**
     * 更新 加工单材料明细 执行情况
     * @param productionWorkDetailCumBoList
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void calculateCumQuantity(List<VProductionWorkDetailCumBo> productionWorkDetailCumBoList) {
        productionWorkDetailCumBoList.forEach(productionWorkDetailCumBo -> {
            Integer calculateType = productionWorkDetailCumBo.getCalculateType();
            Integer businessType = productionWorkDetailCumBo.getBusinessType();
            Integer productionWorkId = productionWorkDetailCumBo.getProductionWorkId();
            HashMap<Long, VProductionWorkInventoryDetailCumBo> productionWorkInventoryDetailCumBoHashMap = productionWorkDetailCumBo.getProductionWorkInventoryDetailCumBoHashMap();
            // 获取  领退补 执行情况
            VProductionWorkMain productionWorkMain = getById(productionWorkId);
            //查询 委外 状态
            Integer voucherState = productionWorkMain.getVoucherState();
            if ( 4 == businessType || 6 == businessType){
                if (10 == voucherState) {
                    throw new NuoNiuException("委外加工单已经关闭，不能再领退或者补料了");
                }
            }

            /*****************************       处理 材料明细 执行情况           ***************************/
            Set<Long> inventoryDetailIds = productionWorkInventoryDetailCumBoHashMap.keySet();
            // 获取 材料明细 详情
            List<VProductionWorkInventoryDetail> productionWorkInventoryDetailList = productionWorkInventoryDetailService.listByIds(inventoryDetailIds);
            //
            productionWorkInventoryDetailList.forEach(productionWorkInventoryDetail->{
                Long inventoryDetailId = productionWorkInventoryDetail.getId();
                BigDecimal plannedQuantity = productionWorkInventoryDetail.getPlannedQuantity();
                VProductionWorkInventoryDetailCumBo vProductionWorkInventoryDetailCumBo = productionWorkInventoryDetailCumBoHashMap.get(inventoryDetailId);
                BigDecimal cumQuantity = vProductionWorkInventoryDetailCumBo.getCumQuantity();
                if (null != cumQuantity){
                    switch (businessType){
                        // 领料
                        case 4:
                            BigDecimal cumPickQuantity = productionWorkInventoryDetail.getCumPickQuantity();
                            BigDecimal cumRetQuantityPick = productionWorkInventoryDetail.getCumRetQuantity();
                            BigDecimal cumRepairQuantityPick = productionWorkInventoryDetail.getCumRepairQuantity();
                            if (null != cumRepairQuantityPick && cumRepairQuantityPick.compareTo(BigDecimal.ZERO) > 0) {
                                throw new NuoNiuException("材料名称：" + productionWorkInventoryDetail.getInventoryName() + " 已经开始补料，请先删除补料数量");
                            }
                            if(null != cumRetQuantityPick && cumPickQuantity.compareTo(cumRetQuantityPick) < 0) {
                                throw new NuoNiuException("材料名称：" + productionWorkInventoryDetail.getInventoryName() + " 的累计领料数量 不能小于 累计退货数量,请先删除退货数量");
                            }
                            if (null == cumPickQuantity){
                                cumPickQuantity = new BigDecimal(0);
                            }

                            if ( 1 == calculateType){
                                cumPickQuantity = cumPickQuantity.add(cumQuantity);
                            }else{
                                cumPickQuantity = cumPickQuantity.subtract(cumQuantity);
                            }
                            if (cumPickQuantity.compareTo(plannedQuantity) > 0) {
                                throw new NuoNiuException("材料名称：" + productionWorkInventoryDetail.getInventoryName() + " 的累计领料数量 不能大于 计划数量");
                            }
                            if (cumPickQuantity.compareTo(BigDecimal.ZERO) < 0) {
                                throw new NuoNiuException("材料名称：" + productionWorkInventoryDetail.getInventoryName() + " 的累计领料数量 不能小于 0");
                            }
                            productionWorkInventoryDetail.setCumPickQuantity(cumPickQuantity);
                            break;
                        // 退料
                        case 5:
                            BigDecimal cumRetQuantity = productionWorkInventoryDetail.getCumRetQuantity();
                            BigDecimal cumPickQuantityRet = productionWorkInventoryDetail.getCumPickQuantity();
                            if (null == cumRetQuantity){
                                cumRetQuantity = new BigDecimal(0);
                            }
                            if ( 1 == calculateType){
                                cumRetQuantity = cumRetQuantity.add(cumQuantity);
                            }else{
                                cumRetQuantity = cumRetQuantity.subtract(cumQuantity);
                            }
                            if (cumRetQuantity.compareTo(cumPickQuantityRet) > 0) {
                                throw new NuoNiuException("材料名称：" + productionWorkInventoryDetail.getInventoryName() + " 的累计退料数量 不能大于 累计领料数量");
                            }
                            if (cumRetQuantity.compareTo(BigDecimal.ZERO) < 0) {
                                throw new NuoNiuException("材料名称：" + productionWorkInventoryDetail.getInventoryName() + " 的累计退料数量 不能小于 0");
                            }
                            productionWorkInventoryDetail.setCumRetQuantity(cumRetQuantity);
                            break;
                        // 补料
                        case 6:
                            BigDecimal cumPickQuantityRepair = productionWorkInventoryDetail.getCumPickQuantity();
                            if(null == cumPickQuantityRepair || cumPickQuantityRepair.compareTo(plannedQuantity) < 0) {
                                throw new NuoNiuException("材料名称：" + productionWorkInventoryDetail.getInventoryName() + " 的累计领料数量 还未达到 计划数量，不能补料");
                            }
                            BigDecimal cumRepairQuantity = productionWorkInventoryDetail.getCumRepairQuantity();
                            if (null == cumRepairQuantity){
                                cumRepairQuantity = new BigDecimal(0);
                            }
                            if ( 1 == calculateType){
                                cumRepairQuantity = cumRepairQuantity.add(cumQuantity);
                            }else{
                                cumRepairQuantity = cumRepairQuantity.subtract(cumQuantity);
                            }
                            productionWorkInventoryDetail.setCumRepairQuantity(cumRepairQuantity);
                            break;
                    }
                }
            });
            productionWorkInventoryDetailService.saveOrUpdateBatch(productionWorkInventoryDetailList);
            /*****************************       处理 材料明细 执行情况           ***************************/
        });
    }



    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteById(Long id) {
        BigDecimal allDetailCumDispatchQuantity = getAllDetailCumDispatchQuantity(id);
        if(null != allDetailCumDispatchQuantity && allDetailCumDispatchQuantity.compareTo(BigDecimal.ZERO) > 0 ) {
            throw new NuoNiuException("已经生产派工单，不能删除");
        }
       this.deleteDelegateById(id);
    }



    /*********************   生产制造 报表统计 开始  **********************/

    @Override
    public Page<ProductionWorkCumSummaryVo> pageProductionWorkCumSummaryVo(ProductionWorkCumSummaryDto dto) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        Page<ProductionWorkCumSummaryVo> productionWorkCumSummaryVoPage = baseMapper.pageProductionWorkCumSummaryVo(dto.getPage(), companyId, dto);
        return productionWorkCumSummaryVoPage;
    }

    @Override
    public Page<ProductionWorkCumDetailVo> pageProductionWorkCumDetailVo(ProductionWorkCumSummaryDto dto) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        Page<ProductionWorkCumDetailVo> productionWorkCumDetailVoPage = baseMapper.pageProductionWorkCumDetailVo(dto.getPage(), companyId, dto);
        return productionWorkCumDetailVoPage;
    }

    @Override
    public Page<ProductionPickReturnCumSummaryVo> pageProductionPickReturnCumSummaryVo(ProductionWorkCumSummaryDto dto) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        Page<ProductionPickReturnCumSummaryVo> productionPickReturnCumSummaryVoPage = baseMapper.pageProductionPickReturnCumSummaryVo(dto.getPage(), companyId, dto);
        return productionPickReturnCumSummaryVoPage;
    }

    @Override
    public Page<ProductionPickReturnCumDetailVo> pageProductionPickReturnCumDetailVo(ProductionWorkCumSummaryDto dto) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        Page<ProductionPickReturnCumDetailVo> productionPickReturnCumDetailVoPage = baseMapper.pageProductionPickReturnCumDetailVo(dto.getPage(), companyId, dto);
        return productionPickReturnCumDetailVoPage;
    }

    @Override
    public Page<ProductionPickAbnormalVo> pageProductionPickAbnormalVo(ProductionWorkCumSummaryDto dto) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        Page<ProductionPickAbnormalVo> productionPickAbnormalVoPage = baseMapper.pageProductionPickAbnormalVo(dto.getPage(), companyId, dto);
        return productionPickAbnormalVoPage;
    }

    @Override
    public Page<ProductionPickAbnormalVo> pageProductionPickAbnormalSumVo(ProductionWorkCumSummaryDto dto) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        Page<ProductionPickAbnormalVo> pageProductionPickAbnormalSumVo = baseMapper.pageProductionPickAbnormalSumVo(dto.getPage(), companyId, dto);
        return pageProductionPickAbnormalSumVo;
    }

    @Override
    public Page<ProductionMonthInVo> pageProductionMonthInVo(ProductionWorkMonthSummaryDto dto) {
        String month = dto.getMonth();
        if(StringUtils.isBlank(month)) {
            throw new NuoNiuException("月份不能为空");
        }
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        Page<ProductionMonthInVo> productionMonthInVoPage = baseMapper.pageProductionMonthInVo(dto.getPage(), companyId, dto);
        return productionMonthInVoPage;
    }

    @Override
    public Page<ProductionPickReturnMonthSummaryVo> pageProductionPickReturnMonthSummaryVo(ProductionWorkMonthSummaryDto dto) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        Page<ProductionPickReturnMonthSummaryVo> productionPickReturnMonthSummaryVoPage = baseMapper.pageProductionPickReturnMonthSummaryVo(dto.getPage(), companyId, dto);
        return productionPickReturnMonthSummaryVoPage;
    }

    @Override
    public Page<ProductionInMainVo> pageProductionInMainVo(ProductionWorkInAndPickDto dto) {
        String inDateStart = dto.getInDateStart();
        String inDateEnd = dto.getInDateEnd();
        if(StringUtils.isBlank(inDateStart)) {
            throw new NuoNiuException("开始时间不能为空");
        }
        if(StringUtils.isBlank(inDateEnd)) {
            throw new NuoNiuException("结束时间不能为空");
        }
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        Page<ProductionInMainVo> productionInMainVoPage = baseMapper.pageProductionInMainVo(dto.getPage(), companyId, dto);
        return productionInMainVoPage;
    }

    @Override
    public List<ProductionPickVo> listProductionPickVo(ProductionWorkInAndPickDto dto) {
        String inDateStart = dto.getInDateStart();
        String inDateEnd = dto.getInDateEnd();
        Integer productionWorkDetailId = dto.getProductionWorkDetailId();
        if(StringUtils.isBlank(inDateStart)) {
            throw new NuoNiuException("开始时间不能为空");
        }
        if(StringUtils.isBlank(inDateEnd)) {
            throw new NuoNiuException("结束时间不能为空");
        }
        if(null == productionWorkDetailId) {
            throw new NuoNiuException("请选择产品");
        }
        UserInfo userInfo = UserThreadLocal.get();
        Integer companyId = userInfo.getCompanyId();
        List<ProductionPickVo> productionPickVos = baseMapper.listProductionPickVo(companyId, dto);
        return productionPickVos;
    }


    /*********************   生产制造 报表统计  结束 **********************/
}
